package com.yg.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yg.config.FilePathConfig;
import com.yg.config.result.R;
import com.yg.config.result.ResultCode;
import com.yg.entity.readAndWriteTemplates.TeachingPracticeBasePlus;
import com.yg.entity.singleEntity.TeachingPracticeBase;
import com.yg.mapper.TeachingPracticeBaseMapper;
import com.yg.service.TeachingPracticeBaseService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 对应sheet16，此表是教学实践基地表 服务实现类
 * </p>
 *
 * @author YingGu
 * @since 2020-11-04
 */
@Service
public class TeachingPracticeBaseServiceImpl extends ServiceImpl<TeachingPracticeBaseMapper, TeachingPracticeBase> implements TeachingPracticeBaseService {
    @Autowired
    private TeachingPracticeBaseMapper teachingPracticeBaseMapper;
    @Autowired
    private FilePathConfig filePathConfig;
    /**
     * 导出文件名
     */
    String outputFileName = "sheet15_output" + System.currentTimeMillis() + ".xlsx";

    /**
     * excel写入
     * @return
     */
    @Transactional
    @Override
    public R readExcel(FileInputStream fileInputStream) {
        //创建要录入的bean的list
        List<TeachingPracticeBase> teachingPracticeBaseList = new ArrayList<>();
        //创建R
        R r = R.getR();
        r.setCode(ResultCode.SUCCESS);
        //存储错误信息
        List<String> errorList = new ArrayList<>();

        //读取excel(匿名内部类解决传参问题)
        EasyExcel.read(fileInputStream, TeachingPracticeBase.class, new AnalysisEventListener<TeachingPracticeBase>() {

            //每行执行
            @SneakyThrows
            @Override
            public void invoke(TeachingPracticeBase teachingPracticeBase, AnalysisContext analysisContext) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                Date date=sdf.parse(teachingPracticeBase.getTime());
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy.MM");
                String time=sdf1.format(date);
                teachingPracticeBase.setTime(time);
                teachingPracticeBase.setDeleted(0);
                teachingPracticeBaseList.add(teachingPracticeBase);
            }

            //所有行读完执行
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                if (r.getCode() == ResultCode.SUCCESS){
                    //向数据库插入数据
                    saveData();
                }else {
                    //添加错误信息
                    r.data("errorMsg",errorList);
                }
            }


            /**
             * 数据类型转换异常处理
             * @param exception
             * @param context
             * @throws Exception
             */
            @Override
            public void onException(Exception exception, AnalysisContext context) throws Exception {
                if (exception instanceof ExcelDataConvertException) {
                    ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;

                    //向errorList中添加信息
                    r.code(ResultCode.ERROR);
                    System.out.println("行："+excelDataConvertException.getRowIndex() + "列" +excelDataConvertException.getColumnIndex());
                    errorList.add("行："+excelDataConvertException.getRowIndex() + "列" +excelDataConvertException.getColumnIndex());
//                    LOGGER.error("第{}行，第{}列解析异常", excelDataConvertException.getRowIndex(),
//                            excelDataConvertException.getColumnIndex());
                }
            }

            //存数据库操作
            private void saveData(){
                for (TeachingPracticeBase teachingPracticeBase : teachingPracticeBaseList) {
                    teachingPracticeBaseMapper.insert(teachingPracticeBase);
                    System.out.println("插入成功");
                }

                //r中写入成功信息
                r.code(ResultCode.SUCCESS).message("插入成功");
            }
        }).headRowNumber(5).sheet().doRead();

        return r;
    }

    /**
     * excel写出
     * @return
     */
    @Transactional
    @Override
    public R writeExcel(String name, HttpServletResponse response) throws IOException {
        List<TeachingPracticeBase> teachingPracticeBases=null;
        if(name==null||"".equals(name)){
            teachingPracticeBases=teachingPracticeBaseMapper.selectList(null);
        }else{
            //表从数据库中查询对应格
            QueryWrapper queryWrapper=new QueryWrapper();
            queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
            teachingPracticeBases = teachingPracticeBaseMapper.selectList(queryWrapper);
        }
        List<TeachingPracticeBasePlus> teachingPracticeBasePluses = new ArrayList<>();
        int i=0;
        //将数据库对应的bean复制给导出表格bean
        for (TeachingPracticeBase teachingPracticeBase1:teachingPracticeBases) { //复制teacher中的属性
            i++;
            TeachingPracticeBasePlus teachingPracticeBasePlus = new TeachingPracticeBasePlus();
            BeanUtils.copyProperties(teachingPracticeBase1,teachingPracticeBasePlus);
            teachingPracticeBasePlus.setOrderNumber(i);
            teachingPracticeBasePluses.add(teachingPracticeBasePlus);
        }
        System.out.println(Arrays.asList(teachingPracticeBasePluses));
        response.setHeader("Content-disposition", "attachment;filename=" + outputFileName);
        //导出(匿名内部类SheetWriteHandler)
        EasyExcel.write(response.getOutputStream()).withTemplate(filePathConfig.writeExcelFilePath + "sheet16Template.xlsx").registerWriteHandler(new SheetWriteHandler() {

            @Override
            public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

            }

            @Override
            public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
                //日志
            }


        }).sheet().doFill(teachingPracticeBasePluses);

        return R.OK();
    }

    /**
     * 查询教师所有信息
     * @return
     */
    @Override
    public R selectAllBaseInfo(int current,int size) {
        //Page类的构造函数中第一个参数为当前查询第几页，第二个参数为每页的记录数(分页查询)
        Page<TeachingPracticeBase> page = new Page<>(current,size);
        teachingPracticeBaseMapper.selectPage(page,null);
        List<TeachingPracticeBase> records = page.getRecords();
        records.forEach(System.out::println);
        System.out.println("总页数" + page.getPages());
        return R.OK().data("list",records).data("pages",page.getPages()).data("total",page.getTotal());
    }

    /**
     * 条件查询
     * @param s
     * @return
     */
    @Override
    public R baseConditionalQuery(String s,int current,int size) {
        IPage<TeachingPracticeBase> baseReadIPage=null;
        Page<TeachingPracticeBase> baseReadPage = new Page<TeachingPracticeBase>(current,size);
        if(s==null||"".equals(s)){
            baseReadIPage=teachingPracticeBaseMapper.selectPage(baseReadPage,null);
        }else{
            TeachingPracticeBase teachingPracticeBase = JSONObject.parseObject(s, TeachingPracticeBase.class);
            baseReadIPage= teachingPracticeBaseMapper.baseConditionalQuery(baseReadPage, teachingPracticeBase);
        }
        List<TeachingPracticeBase> records = baseReadIPage.getRecords();
        return records.size() != 0 ? R.OK().data("list",records).data("pages",baseReadPage.getPages()).data("total",baseReadPage.getTotal()): R.OK().message("您所查询的信息不存在");
    }

    /**
     * 更新用户信息
     * @param s
     * @return
     */

    @Transactional
    @Override
    public R updateBaseInfo(String s) {
        //Json转换
        TeachingPracticeBase teachingPracticeBase = JSONObject.parseObject(s, TeachingPracticeBase.class);
        //构造条件
        QueryWrapper<TeachingPracticeBase> teacherQueryWrapper = new QueryWrapper<>();
        teacherQueryWrapper.eq("id",teachingPracticeBase.getId());
        //返回数值1+1
        int baseUpdate = teachingPracticeBaseMapper.update(teachingPracticeBase, teacherQueryWrapper);

        return baseUpdate == 1 ? R.OK().message(teachingPracticeBase.getName() + "修改成功") : R.ERROR().code(ResultCode.UPDATEERROR).message(teachingPracticeBase.getName() + "修改失败");
    }
    /**
     * 删除教学基地
     * @param id
     * @return
     */
    @Transactional
    @Override
    public R deleteBaseById(String id) {
        //Json转换
        TeachingPracticeBase teachingPracticeBase = JSONObject.parseObject(id, TeachingPracticeBase.class);
        int id1 = teachingPracticeBaseMapper.delete(new QueryWrapper<TeachingPracticeBase>().eq("id", teachingPracticeBase.getId()));
        return id1 == 1 ? R.OK().message("删除成功") : R.ERROR().code(ResultCode.DELETEERROR).message("删除失败");
    }

    /**
     * 增加教学基地
     * @param teachingPracticeBase 新添加的基地信息
     */
    public R insertBase(String teachingPracticeBase){
        //Json转换
        TeachingPracticeBase convert = JSONObject.parseObject(teachingPracticeBase, TeachingPracticeBase.class);
        convert.setDeleted(0);
        int row=teachingPracticeBaseMapper.insert(convert);
        return row == 1 ? R.OK().message("增加成功") : R.ERROR().code(ResultCode.INSERTERROR).message("增加失败");
    }



}
